home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
bd3.zip
/
PRINT.ME
< prev
next >
Wrap
Text File
|
1989-04-30
|
74KB
|
1,696 lines
BANK DEMO 3BANK DEMO 3
A Demonstration of Tasking in AdaA Demonstration of Tasking in Ada
Version 1.0, 11 March 1989
by
Richard Conn
Bank Demo 3, or BD3 as the files and mainline procedure are named, is a
demonstration program which illustrates how Ada and its tasking mechanism can
be used to create a model of an activity in the real world. BD3 is a model of
a bank, where the bank contains several tellers, implemented as Ada tasks, and
is used by customers, also implemented as Ada tasks. The user at the console
can monitor the status of the bank and the accounts of its customers and cause
more customer tasks to execute, thereby increasing the level of activity at
the bank. The tasks all operate in parallel, so a variety of events can be
thought of as happening at the same time, controlled by the Ada runtime system
which is built into the Ada program by the Ada compilation system.
This document and the associated software are presented as an
introduction to the Ada language and its tasking capabilities. While the
author attempted to make this document as easy to follow as possible, a
limited knowledge of Ada is assumed. Variable assignments, type definitions,
and procedure and package specifications are presented in correct Ada syntax
without much explanation. If this proves to be a problem, the ADA-TUTR
shareware program will help a lot in bringing the user up to date with an
understanding of Ada syntax. Regardless, the program in the file BD3.EXE can
be run without any knowledge of Ada at all, and the tasking demonstration can
be observed.
BANK DEMO 3
A Demonstration of Tasking in Ada
by Richard Conn
1 Introduction 1 Introduction
BD3 is a model of a bank. The Ada package called BANK represents the
bank itself, and the bank contains four tellers, represented by an array,
named TELLER, of four tasks. BD3 is written in an object-oriented fashion in
the Ada programming language.
======================================================================
ADD_NEW_CUSTOMER
-- to create a new account for a customer and return
-- an ID for that customer
GET_BALANCE
-- to return the balance of a customer's account
MAKE_DEPOSIT
-- to deposit money into a customer's account
MAKE_WITHDRAWAL
-- to withdraw money from a customer's account
Figure 1: The bank tellers can process four kinds of transactions. Figure 1
======================================================================
Each task, TELLER(1) to TELLER(4), supports one entry point, called
REQUEST, which is used by tasks outside the BANK package to communicate with a
TELLER(n) task and request a transaction. Four transaction requests are
recognized by a TELLER(n) task, as shown in Figure 1.
BD3 - A Demonstration of Tasking in Ada
======================================================================
MY_ID : BANK.CUSTOMER_ID;
-- MY_ID is a variable which holds the customer ID of
-- this task (type CUSTOMER_ID is defined in the package BANK)
AMOUNT : BANK.DOLLAR;
-- type DOLLAR represents the unit of currency, as defined
-- by the package BANK, and the variable AMOUNT is used to
-- hold the money passed in to or out of the TELLER(n) task
...
BANK.TELLER(1).REQUEST (MY_ID, BANK.ADD_NEW_CUSTOMER, AMOUNT);
-- this calls the REQUEST entry point for the task TELLER(1)
-- in the package BANK; the ID of the customer is passed
-- out of the TELLER(1) task in the variable MY_ID and the
-- requested transaction is ADD_NEW_CUSTOMER, which is
-- defined in the package BANK; the variable AMOUNT is
-- passed as a parameter but not used
AMOUNT := 100.00;
BANK.TELLER(2).REQUEST (MY_ID, BANK.MAKE_DEPOSIT, AMOUNT);
-- the variable AMOUNT is set to $100, and the REQUEST
-- entry point of TELLER(2) in the package BANK is
-- called; the variable MY_ID, which was set by the call
-- to TELLER(1) above, is used to identify the customer,
-- and the requested action is MAKE_DEPOSIT, as defined by
-- the package BANK; AMOUNT is passed to the TELLER(2) task
-- as the amount to deposit
Figure 2: This code segment shows that the TELLER(n) tasks are accessed like procedures. Figure 2
======================================================================
Each TELLER(n) task performs one of these four transactions at a time.
An external task calls (makes a rendezvous with, in Ada terminology) a
TELLER(n) task through its REQUEST entry point, passing one of these
transaction names as a parameter, and the TELLER(n) task processes the
request. For example, a code segment in an external task may look something
like Figure 2. This code segment was extracted from the body of the CUSTOMER
task definition in the package CUSTOMER_WORLD (see later).
This demonstration program also contains several other tasks, called
customer tasks. These tasks, hidden inside the package CUSTOMER_WORLD,
operate independently and interact with the various teller tasks. The
customer tasks make requests to the teller tasks, asking to be added as a
customer of the bank, making deposits, and making withdrawals. Using the Ada
inter-task rendezvous mechanism to communicate, if the teller task is already
servicing another customer task, the customer task "waits in line" (having
been placed in the implicit queue associated with the teller's entry point).
If queued, the customer task is serviced after the tasks in the teller's queue
in front of him have been serviced. Indeed, the model is similar to the real
world.
From the mainline procedure, the user can monitor the bank and its
activity. He can obtain a status report from the bank (which includes the
balanace of each customer, the number of transactions requested by each
customer, and the number of transactions processed by each teller), cause new
customer tasks to start up, and shut down the system and exit the program.
- 2 -
BD3 - A Demonstration of Tasking in Ada
For those Ada compilers which do not allow tasking to proceed while the
current task is waiting for input (such as many of the Ada compilers available
for the IBM PC), a continuous display function is also provided to the user
which displays the bank's status, delays five seconds (allowing the various
tasks to run), and displays the bank's status again. This command option
displays ten status reports before returning the user to his prompt.
2 Execution of the Program 2 Execution of the Program
Figures 3 to 9 show various displays during the execution of the program.
These displays were generated on a SUN workstation, where the program was
compiled by the Verdix Ada compiler. These displays may be different from
what you see if you compile the program on an IBM PC, particularly in that
Verdix Ada does not suspend all tasks while the current task is waiting for
input from the console. While we are at the prompt in these figures, all
tasks are running in parallel with our input activity. On some compilers this
will not be the case, and the parallel operation of the tasks will not be seen
until the user issues the 'c' (continuous bank status) command.
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
The bank doesn't have any customers
Figure 3: When BD3 starts, there are no customers. Figure 3
======================================================================
Figure 3 shows the menu that is presented to the user when the program
starts and that no customer tasks are running yet.
- 3 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 100.00 2 0
Teller : 1 2 3 4
Transaction_Count: 0 1 1 0
Figure 4: The 's' command starts a new customer task. Figure 4
======================================================================
Figure 4 shows the start of the first customer task via the 's' command
followed immediately by a status report of the bank (requested via the 'b'
command). The task we just started has had enough time between the start of
the task and the request of the status display to perform 2 transactions, and
we can see that tellers 2 and 3 were selected to perform these transactions.
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 95.26 3 0
Teller : 1 2 3 4
Transaction_Count: 0 2 1 0
Figure 5: Another status display shows just a little activity by the customer. Figure 5
======================================================================
Figure 5 shows another bank status command, which was issued as soon as
the display above completed. During this brief amount of time, the customer
has had time to perform another transaction.
- 4 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 100.59 5 0
2 123.13 4 0
3 117.75 3 0
4 114.97 3 0
5 100.00 2 0
6 38.86 4 0
Teller : 1 2 3 4
Transaction_Count: 5 7 7 2
Figure 6: Five more tasks are started up. Figure 6
======================================================================
Five more customer tasks are started up in Figure 6 and another bank
status display is requested. The fact that we have many tasks running in
parallel now should become evident as we see more and more activity going on
between each of our status displays.
- 5 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: c
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 134.37 7 0
2 131.77 5 0
3 202.01 5 0
4 129.76 4 0
5 100.00 2 0
6 57.83 5 0
Teller : 1 2 3 4
Transaction_Count: 9 9 7 3
...
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 73.44 29 3
2 206.04 24 0
3 165.82 27 0
4 58.48 24 3
5 71.03 22 0
6 41.02 27 2
Teller : 1 2 3 4
Transaction_Count: 60 36 38 19
Figure 7: A continous bank status display shows a lot of activity over a short time. Figure 7
======================================================================
Figure 7 shows a 'c' (continue bank status) command and its resulting
display. To save space, I have shown only the first and the last of the
eleven bank status report displays generated by this command.
- 6 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: s
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 108.96 31 3
2 226.90 26 0
3 106.79 30 0
4 87.86 26 3
5 57.83 24 0
6 23.36 30 3
7 50.89 3 0
8 100.00 2 0
Teller : 1 2 3 4
Transaction_Count: 68 42 42 21
Figure 8: Two more customer tasks are started. Figure 8
======================================================================
In Figure 8, two more customer tasks are started and the result is shown.
There are now 8 customer tasks, 4 teller tasks, and the mainline procedure (as
another task) running in this Ada system.
- 7 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 127.88 34 3
2 232.11 28 0
3 56.17 33 0
4 110.24 28 3
5 81.60 28 0
6 4.68 32 3
7 31.60 6 1
8 54.42 4 0
Teller : 1 2 3 4
Transaction_Count: 79 48 44 22
Enter
b for bank status
c for continuous bank status
s for start next customer
x for exit: b
**** BANK STATUS REPORT ****
Customer Balance Transactions Attempted_Overdraws
1 63.89 37 3
2 147.16 32 0
3 48.62 38 0
4 272.81 36 3
5 62.22 34 0
6 74.99 36 4
7 59.31 10 1
8 72.42 9 0
Teller : 1 2 3 4
Transaction_Count: 94 59 56 24
Figure 9: Two more status reports are shown, each after some delay. Figure 9
======================================================================
Figure 9 shows two more bank status displays. The user of the program
has delayed for some time before issuing these commands so that a significant
level of activity can be shown.
More activity could be displayed, and more customer tasks could be
started, but the displays shown so far should be enough to give the reader a
good feel for the program's operation. When the user is finished, the 'x'
(for exit) command will terminate all tasks and return the user to the
operating system.
The displays presented so far were generated by the BD3 mainline
procedure running on a UNIX system, having been compiled by the Verdix Ada
compiler. BD3.EXE provided in the distribution was compiled under the
- 8 -
BD3 - A Demonstration of Tasking in Ada
IntegrAda environment. The reader will see similar displays when BD3.EXE is
executed with the exception that no other tasks will run when the prompt is
displayed. In order for multitasking to be observed when running BD3.EXE, the __________________________________________________________________
user must issue the 'c' (for continuous bank status) command. Once the delay ______________________________________________________________
statement in the mainline is encountered, the Ada runtime system is allowed to
come into play and other tasks are then permitted to run.
3 Discussion of the Design 3 Discussion of the Design
BD3 is an object-oriented design. The objects contained in this Ada
system are a console device (defined by the Ada package CONSOLE) which
supports input and output from and to the user's console terminal, a random
number generator (defined by the Ada package RANDOM) which generates random
numbers of type FLOAT in the range from 0.0 to 1.0, the bank (defined by the
Ada package BANK) which contains the four TELLER(n) objects (defined by the
Ada task type TELLER_PERSON) and the basic type definitions (such as
TRANSACTION, CUSTOMER_ID, and DOLLAR) which are used to communicate with a
TELLER(n) object, and the base of customers (defined by the Ada package
CUSTOMER_WORLD) which interacts with the tellers in the bank.
The specification to the package CONSOLE is shown in Figures 10, 11, and
12. Each line is numbered for the convenience of the reader (of course, these
numbers do not appear in the files which are compiled by an Ada compiler).
- 9 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
1 package CONSOLE is
2 --------------------------------------------------------------------------
3 --| BEGIN PROLOGUE
4 --| DESCRIPTION : CONSOLE is a package which implements an
5 --| : abstract state machine, a console terminal,
6 --| : that maps to the user's terminal. CONSOLE
7 --| : provides routines to output characters,
8 --| : strings, integers, and floats (real numbers)
9 --| : to the user's terminal. CONSOLE provides
10 --| : a routine to input a string of text from the
11 --| : user's terminal. Finally, CONSOLE provides
12 --| : a function which can trim leading spaces
13 --| : from a string of text (useful in outputting
14 --| : text which was input by the read routine).
15 --| :
16 --| REQUIREMENTS SUPPORTED : A simple I/O package for Ada programs
17 --| :
18 --| LIMITATIONS : Text input by CONSOLE.READ can be no more
19 --| : than 80 characters long. Only objects of
20 --| : type CHARACTER, STRING, INTEGER, and FLOAT
21 --| : can be output.
22 --| :
23 --| AUTHOR(S) : Richard Conn
24 --| CHANGE LOG : 08/30/88 RLC Initial Design and Code
25 --| :
26 --| REMARKS : None
27 --| :
28 --| PORTABILITY ISSUES : Uses TEXT_IO, so is very portable; no known
29 --| : portability problems.
30 --| END PROLOGUE
31 --------------------------------------------------------------------------
32
Figure 10: Specification of Package CONSOLE, Part 1 of 4 Figure 10
======================================================================
In Figure 10, the prologue in the specification of the package CONSOLE is
given. Line 1 is the only piece of processed code; the rest of the lines are
Ada comments which describe the package and give other information about it.
I developed this package some time ago for use in my Ada classes, feeling that
the package TEXT_IO (which is supplied with all Ada compilers) is too complex
for most beginners to work with. Package CONSOLE starts to introduce an
object-oriented design to Ada code design and is simple to use.
- 10 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
33 -- Special items to print
34 type SPECIAL_ITEM is (NEW_LINE, TAB, BACKSPACE);
35
36 -- Type of string used by READ procedure
37 subtype OUTSTRING is STRING(1 .. 80);
38
39 procedure WRITE(ITEM : in STRING);
40 procedure WRITE(ITEM : in CHARACTER);
41 -- Print strings and characters
42 -- Examples:
43 -- Ada procedure call Prints (without quotes)
44 -- ============================ =======================
45 -- CONSOLE.WRITE ("This is a test"); "This is a test"
46 -- CONSOLE.WRITE ('?'); "?"
47
48 procedure WRITE(ITEM : in SPECIAL_ITEM);
49 -- Print special items
50 -- Example:
51 -- Ada procedure call Prints (without quotes)
52 -- ============================ =======================
53 -- CONSOLE.WRITE (CONSOLE.NEW_LINE); <advances to next line>
54
55 --
56 -- Package CONSOLE
57
58 procedure WRITE(ITEM : in INTEGER; WIDTH : in NATURAL := 0);
59 -- Print integers
60 -- Examples:
61 -- Ada procedure call Prints (without quotes)
62 -- ============================ =======================
63 -- CONSOLE.WRITE (25); "25"
64 -- CONSOLE.WRITE (-3); "-3"
65 -- CONSOLE.WRITE (25, 5); " 25"
66
Figure 11: Specification of Package CONSOLE, Part 2 of 4 Figure 11
======================================================================
Figure 11 contains more of the specification of package CONSOLE, showing
the two type definitions used by procedures within the package and four
procedure specifications, all for procedures named WRITE (see lines 39, 40,
48, and 58). These procedures, all similarly named, differ in the types of
arguments they accept, and Ada determines which procedure is reference by the
types of the arguments used when the call to the procedure is made. The
comment blocks in lines 41-46, 49-53, and 59-65 contain examples of how these
procedures would be called from outside of package CONSOLE.
Note that the WRITE procedure on line 58 accepts two parameters, an
INTEGER and a NATURAL number with a default value. The default value of 0 for
the WIDTH parameter tells the procedure to use as many spaces as necessary to
output the number. As indicated by lines 63-65, the WIDTH parameter does not
have to be referenced when the procedure is called.
- 11 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
67 procedure WRITE(ITEM : in FLOAT;
68 BEFORE_DECIMAL : in NATURAL := 5;
69 AFTER_DECIMAL : in NATURAL := 5);
70 procedure WRITE_SCIENTIFIC(ITEM : in FLOAT;
71 AFTER_DECIMAL : in NATURAL := 8);
72 -- Print floats
73 -- Examples:
74 -- Ada procedure call Prints (without quotes)
75 -- ============================ =======================
76 -- CONSOLE.WRITE (25.21); " 25.21000"
77 -- CONSOLE.WRITE (-36.2); " -36.20000"
78 -- CONSOLE.WRITE (-36.2, 1, 1); "-36.2"
79 -- CONSOLE.WRITE (25.21, 3); " 25.21000"
80 -- CONSOLE.WRITE (25.21, 3, 2); " 25.21"
81 -- CONSOLE.WRITE_SCIENTIFIC (23.0); " 2.30000000e+01"
82 -- CONSOLE.WRITE_SCIENTIFIC (5.7, 2); " 5.70E+00"
83 -- CONSOLE.WRITE_SCIENTIFIC (-4.5e-24, 4); "-4.5000E-24"
84
Figure 12: Specification of Package CONSOLE, Part 3 of 4 Figure 12
======================================================================
Figure 12 contains the next part of the specification for package
CONSOLE. Lines 67-69 define the specification for a WRITE procedure which
works on objects of type FLOAT (floating point) to output them in the form
"nn.nn" while lines 70-71 define the specification for a WRITE_SCIENTIFIC
procedure which also works on objects of type FLOAT but outputs them in
scientific notation.
- 12 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
85 procedure READ(ITEM : out OUTSTRING);
86 -- Read strings
87 -- Example (note: <CR> refers to the RETURN key):
88 -- MY_STRING : CONSOLE.OUTSTRING; -- 80-char string
89 -- Ada procedure call User Types In MY_STRING
90 -- ==================== ========== ============
91 -- CONSOLE.READ (MY_STRING); "Hi<CR>" "Hi"<and 78 spaces>
92
93 function TRIM(ITEM : in STRING) return STRING;
94 -- Generate a string which has no trailing spaces
95 -- Example of use:
96 -- MY_STRING : CONSOLE.OUTSTRING;
97 -- CONSOLE.READ(MY_STRING);
98 -- CONSOLE.WRITE("Hello, ");
99 -- CONSOLE.WRITE(CONSOLE.TRIM(MY_STRING));
100 -- CONSOLE.WRITE(", how are you?");
101 -- If the CONSOLE.READ statement returns "Joe" followed by 77 spaces,
102 -- the output will look like "Hello, Joe, how are you?"
103
104 end CONSOLE;
Figure 13: Specification of Package CONSOLE, Part 4 of 4 Figure 13
======================================================================
Figure 13 shows the last part of package CONSOLE. Procedure READ on line
85 always returns an object of type OUTSTRING, which is 80 characters long.
When this procedure is called, the next line typed by the user is returned.
If it is less than 80 characters long, trailing spaces are appended to it. If
it is more than 80 characters long, the first 80 characters are returned and
the next call to READ returns the next 80. For the convenience of the user,
the function TRIM (line 93) is provided to convert a string of any length to
one of another length that contains all characters of the input string except
the trailing spaces.
======================================================================
MY_NUMBER : FLOAT; -- variable definition
...
MY_NUMBER := RANDOM.NUMBER; -- compute the next random number
Figure 14: Calling the Random Number Generator Figure 14
======================================================================
The random number generator object used by the Bank Demo Ada system is
defined by the Ada package named RANDOM. Figure 15 contains the specification
of this package. RANDOM contains only one function, named NUMBER, which
requires no input parameters and returns the next random number as an object
of type FLOAT. A code segment like the one in Figure 14 is used to call the
NUMBER function in package RANDOM:
- 13 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
1 package RANDOM is
2 --------------------------------------------------------------------------
3 --| BEGIN PROLOGUE
4 --| DESCRIPTION : Package RANDOM contains the function NUMBER
5 --| : which returns a pseudo-random number
6 --| : of type FLOAT in the range 0.0 .. 1.0.
7 --| :
8 --| REQUIREMENTS SUPPORTED : Random Number Generator
9 --| :
10 --| LIMITATIONS : None
11 --| :
12 --| AUTHOR(S) : Richard Conn (RLC) from Bill Whitaker's work
13 --| CHANGE LOG : 09/30/88 RLC Design, code, test from
14 --| : Bill Whitaker's original work
15 --| : 10/11/88 RLC Modified based on ideas from
16 --| : Ron Bell and his RAN2 Package
17 --| :
18 --| REMARKS : None
19 --| :
20 --| PORTABILITY ISSUES : Uses 16-bit integers, so should be quite
21 --| : portable
22 --| END PROLOGUE
23 --------------------------------------------------------------------------
24
25 function NUMBER return FLOAT;
26 -- Return a floating point pseudo-random number
27
28 end RANDOM;
Figure 15: Specification of Package RANDOM Figure 15
======================================================================
If you look at the body of package RANDOM, which is included in the
source code distributed with Bank Demo, you will find that RANDOM contains a
hidden procedure called SEED that sets the first random number in the sequence
based on the time-of-day clock value returned by the Ada-standard package
called CALENDAR. Procedure SEED, however, is not needed by the outside world,
so package RANDOM does not make it available.
- 14 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
1 package BANK is
2 --------------------------------------------------------------------------
3 --| BEGIN PROLOGUE
4 --| DESCRIPTION : BANK defines a bank, the TELLER objects
5 --| : within it, and the procedure PRINT_REPORT
6 --| : (which reports on the status of the BANK).
7 --| :
8 --| : BANK is an abstract state machine, defining
9 --| : a BANK object which contains TELLER objects.
10 --| :
11 --| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
12 --| : object-oriented design and tasking
13 --| : with Ada
14 --| :
15 --| LIMITATIONS : None
16 --| AUTHOR(S) : Richard Conn (RLC)
17 --| CHANGE LOG : 1/16/89 RLC Initial Design and Code
18 --| CHANGE LOG : 2/25/89 RLC Final Review Prior to Release
19 --| REMARKS : None
20 --| PORTABILITY ISSUES : None
21 --| END PROLOGUE
22 --------------------------------------------------------------------------
23
Figure 16: Specification of Package BANK, Part 1 of 4 Figure 16
======================================================================
Figure 16 contains the prologue of the specification of package BANK,
which defines the bank object. Note that the tellers are implemented as tasks
(I refer to the tellers in a general sense as TELLER(n), where n is 1 to 4 to
indicate which teller).
======================================================================
24 -- TRANSACTION requested of a TELLER
25 type TRANSACTION is (ADD_NEW_CUSTOMER,
26 GET_BALANCE,
27 MAKE_DEPOSIT,
28 MAKE_WITHDRAWAL);
29
30 -- Unit of currency
31 type DOLLAR is new FLOAT;
32
33 -- Identification of a CUSTOMER
34 type CUSTOMER_ID is new NATURAL range 1 .. NATURAL'LAST;
35
Figure 17: Specification of Package BANK, Part 2 of 4 Figure 17
======================================================================
- 15 -
BD3 - A Demonstration of Tasking in Ada
Figure 17 shows more of the specification of package BANK. The type
definitions are presented first. Lines 25-28 define type TRANSACTION, which
are the transactions which may be requested of a TELLER(n) object. The
transactions which may be performed by a teller are ADD_NEW_CUSTOMER,
GET_BALANCE, MAKE_DEPOSIT, and MAKE_WITHDRAWAL. Line 31 defines type DOLLAR,
which is the unit of currency for the bank. DOLLAR is implemented as a
floating point number, derived from type FLOAT, but DOLLAR objects are unique
from FLOAT objects by this type definition (DOLLAR is a derived type in Ada)
and we cannot interchange the use of a DOLLAR object and a FLOAT object. Line
34 defines type CUSTOMER_ID, which is the ID number associated with each
customer. When a transaction is made with a teller, the customer presents his
ID number to identify himself along with his transaction request. Like
DOLLAR, CUSTOMER_ID is a derived type, but CUSTOMER_ID is derived from type
NATURAL and can take on values from 1 to NATURAL'LAST (the largest value
allowed for objects of type NATURAL).
======================================================================
36 -- Index of and Number of TELLER objects within the bank
37 type TELLER_INDEX is new NATURAL range 1 .. 4;
38
39 -- A TELLER_PERSON is an object to which a CUSTOMER may make a REQUEST
40 -- The BANK tells the TELLER_PERSON to START_WORK, giving the
41 -- TELLER_PERSON its TELLER_NUMBER
42 task type TELLER_PERSON is
43 entry REQUEST(ID : in out CUSTOMER_ID;
44 KIND : in TRANSACTION;
45 AMOUNT : in out DOLLAR);
46 end TELLER_PERSON;
47 -- These are the TELLER objects available at the bank
48 TELLER : array(TELLER_INDEX) of TELLER_PERSON;
49
Figure 18: Specification of Package BANK, Part 3 of 4 Figure 18
======================================================================
In Figure 18, line 37 defines type TELLER_INDEX, which is used to
identify the desired teller. Type TELLER_INDEX is derived from type NATURAL
and restricted in range from 1 to 4. If the user wishes to modify this
program and add more tellers to the model, he need only change the 4 on line
37 to the desired number. The parts of the code which need to know how many
tellers are available at the bank reference TELLER_INDEX'LAST, which is the
largest value that objects of type TELLER_INDEX can take on.
Task type TELLER_PERSON on lines 42-46 defines the interface to all tasks
of type TELLER_PERSON. A TELLER_PERSON task contains one entry point, called
REQUEST, which can be called by tasks external to package BANK. Three
parameters must be specified when the REQUEST entry point is called: the ID of
the customer (type CUSTOMER_ID), the KIND of transaction (type TRANSACTION),
and the AMOUNT associated with the transaction (type DOLLAR).
The task body of TELLER_PERSON is not contained in the specification of
package BANK, but it is hidden in the body of package BANK. You can see this
code by looking at the source code provided in the distribution. In summary,
tasks of type TELLER_PERSON are quite simple in their operation. When a task
- 16 -
BD3 - A Demonstration of Tasking in Ada
of type TELLER_PERSON starts running, it calls the internal task
TELLER_ASSIGNER (which is hidden inside of package BANK) in order to get its
ID number. As each customer has an ID, so each teller also has an ID. The
teller's ID is used to keep a running record of the number of transactions
each teller makes. After it gets it's ID number, a task of type TELLER_PERSON
enters an infinite loop in which it waits for an external task to call its
REQUEST entry point, processes the request from this external task based on
the KIND of transaction requested, and then resumes the loop. It is left as
an exercise to the reader to read the code and figure out exactly what happens
for each KIND of transaction.
Line 48 defines the array, named TELLER, of tellers in the bank. Each
element of this array is of type TELLER_PERSON, making each element an
independent task as opposed to what the reader may normally think of as an
array (which is an array of values stored in memory). The array TELLER is
indexed by TELLER_INDEX, taking on index values from 1 to 4. Hence, four
tasks are created by the array declaration on line 48: TELLER(1), TELLER(2),
TELLER(3), and TELLER(4). Each task starts running during initialization of
the Ada system before the first line of code of the mainline procedure is
executed.
======================================================================
50 -- PRINT_REPORT gives the transaction log of all the bank
51 -- customers
52 procedure PRINT_REPORT;
53
54 -- STOP_WORK terminates all TELLER tasks
55 procedure STOP_WORK;
56 end BANK;
Figure 19: Specification of Package BANK, Part 4 of 4 Figure 19
======================================================================
Package BANK also exports two procedures, as shown in Figure 19:
PRINT_REPORT and STOP_WORK. PRINT_REPORT (whose specification is on line 52)
prints a report of the status of the bank. This report indicates the number
of transactions requested by each customer, the balance of each customer's
account, and the number of transactions processed by each teller. These items
of information are updated constantly by the TELLER(n) tasks by means of a
data base kept internal to package BANK. The outside world does not need to
know that this data base exists or what form it exists in; the outside world
only needs to know that it can print this report based on information in the
data base. PRINT_REPORT is called by the BD3 mainline procedure whenever the
user at the console asks for it or during the running of the continuous status
display command issued by the user. STOP_WORK (whose specification is on line
55) terminates all of the TELLER(n) tasks. STOP_WORK is called by the BD3
mainline procedure when the user asks for the program to shut down (the exit
command). All tasks of the Ada system must be terminated before the mainline
procedure, which is also a task, may terminate. STOP_WORK represents a
function that would be performed by a bank when it closes and it is reasonable
to provide it as part of the specification of package BANK as opposed to
relying upon the mainline procedure to abort each of the TELLER(n) tasks on a
task-by-task basis.
- 17 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
282 package CUSTOMER_WORLD is
283 --------------------------------------------------------------------------
284 --| BEGIN PROLOGUE
285 --| DESCRIPTION : CUSTOMER_WORLD is an abstract state machine
286 --| : which defines the collection of all CUSTOMERs
287 --| : of the BANK. It allows the mainline procedure
288 --| : to ADD a new CUSTOMER and TERMINATE_ALL
289 --| : current CUSTOMERs. The CUSTOMER itself acts
290 --| : as an independent task and requires no
291 --| : direct interaction with the mainline once
292 --| : it starts.
293 --| :
294 --| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
295 --| : object-oriented design and tasking
296 --| : with Ada
297 --| :
298 --| LIMITATIONS : None
299 --| AUTHOR(S) : Richard Conn (RLC)
300 --| CHANGE LOG : 1/16/89 RLC Initial Design and Code
301 --| CHANGE LOG : 2/25/89 RLC Final Review Prior to Release
302 --| REMARKS : None
303 --| PORTABILITY ISSUES : None
304 --| END PROLOGUE
305 --------------------------------------------------------------------------
306
307 -- Add another CUSTOMER task to the system
308 procedure ADD;
309
310 -- Terminate all CUSTOMERs in the system
311 procedure TERMINATE_ALL;
312
313 end CUSTOMER_WORLD;
Figure 20: Specification of Package CUSTOMER_WORLD Figure 20
======================================================================
Figure 20 contains the specification of the package CUSTOMER_WORLD. This
package contains, hidden within it, all of the customer tasks which are
running in the system. Internally, package CUSTOMER_WORLD keeps track of
these tasks by creating a linked list which points to each of them. The
procedure ADD (whose specification is on line 308) causes the package
CUSTOMER_WORLD to spawn another customer task, updating the linked list when
it does so. When each customer task is spawned, it begins running
immediately, performing the functions of an independent customer. There are
no entry points to a customer; the outside world does not request access to a
customer, and the customer tasks each act independently of each other,
requesting access to the TELLER(n) tasks in the bank to perform transactions
as they need them. Each time the user issues the "start new customer" command
from the console, procedure CUSTOMER_WORLD.ADD is called to perform this
function, and a new customer task starts running.
- 18 -
BD3 - A Demonstration of Tasking in Ada
As mentioned in the discussion of package BANK, all children tasks have
to be aborted before the mainline procedure can terminate, and package
CUSTOMER_WORLD exports the procedure TERMINATE_ALL to do this. TERMINATE_ALL
moves through the linked list of tasks, aborting each one as it is
encountered. The BD3 mainline procedure calls CUSTOMER_WORLD.TERMINATE_ALL
just like it calls BANK.STOP_WORK when the exit command is processed.
The task specification and body of a customer (the task type is named
CUSTOMER) is hidden in the body of package CUSTOMER_WORLD. Each customer task
performs the following sequence of operations:
1. The customer selects a TELLER(n) task at random using the random number
generator (function NUMBER in package RANDOM). The customer issues an
ADD_NEW_CUSTOMER transaction through the REQUEST entry point of the selected
TELLER(n) task. The selected TELLER(n) task returns the customer task's ID
number, which the customer task stores for use on all future transactions with
all TELLER(n) tasks.
2. The customer, using his ID number, then selects a TELLER(n) task at
random and issues a MAKE_DEPOSIT transaction through that teller's REQUEST
entry point. The customer deposits $100.00 (see lines 325 and 379-380 in the
full listing of BD3 distributed with this document).
3. The customer now enters an infinite loop, which he stays in for the rest
of his life (until he is aborted by the user at the console issuing the exit
command). This loop (see lines 389-399 of the source listing) consists of the
following steps:
3.1. Delay a random amount of time from 0 to 5 seconds.
3.2. Generate a random amount of money from -$50.00 to $50.00. If the
amount is negative, select the current transaction to be MAKE_WITHDRAWAL and
make the amount positive. If the amount is positive, select the current
transaction to be MAKE_DEPOSIT.
3.3. Select a TELLER(n) task at random, call that teller's REQUEST entry
point, passing to it the his ID number, the desired transaction, and the
amount. The TELLER(n) task will then process the transaction, allowing a
withdrawal only if the customer has sufficient funds to cover the request.
Figures 21 to 24 contain the source code of the mainline procedure for
this Ada system, procedure BD3 (short for Bank Demo 3). This procedure is
where the execution of the mainline begins. All tasks which were declared
statically as objects, such as the TELLER(n) tasks of package BANK, will have
already been initialized and begun execution before the first line of this
procedure is executed. The customer tasks will be dynamically created during
the execution of this procedure, where a new customer task will be created
each time the user issues the "start next customer" command from the console.
- 19 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
442 with BANK;
443 with CUSTOMER_WORLD;
444 with CONSOLE;
445 procedure BD3 is -- BANK_DEMO_3
446 ------------------------------------------------------------------------
447 --| BEGIN PROLOGUE
448 --| DESCRIPTION : Procedure BD3 (BANK DEMO 3) is a mainline
449 --| : which demonstrates the operation of the
450 --| : BANK. Upon invocation, the console becomes
451 --| : a command processor for the bank manager.
452 --| : The bank manager can obtain the status of
453 --| : the bank (balances, number of transactions,
454 --| : and attempted overdraws of all customers
455 --| : and number of transactions processed by all
456 --| : tellers) in a single or continuous (group
457 --| : of 11 over about one minute) display.
458 --| : The user at the console can also cause new
459 --| : Customer tasks to be created and shut down
460 --| : the system.
461 --| :
462 --| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
463 --| : object-oriented design and tasking
464 --| : with Ada
465 --| :
466 --| LIMITATIONS : None
467 --| AUTHOR(S) : Richard Conn (RLC)
468 --| CHANGE LOG : 1/16/89 RLC Initial Design and Code
469 --| CHANGE LOG : 2/25/89 RLC Final Review Prior to Release
470 --| REMARKS : None
471 --| PORTABILITY ISSUES : Uses CONSOLE (TEXT_IO), so is very portable;
472 --| : no known portability problems.
473 --| END PROLOGUE
474 ------------------------------------------------------------------------
475
Figure 21: Procedure BD3, Part 1 of 4 Figure 21
======================================================================
In Figure 21, lines 442-444 establish the context in which the procedure
functions. In particular, the procedure BD3 needs to know about package BANK,
package CUSTOMER_WORLD, and package CONSOLE. These Ada packages must be
previously compiled into the current program unit library before procedure BD3
can be compiled. The Ada compiler will check all interfaces (such as
procedure and object names, parameters passed to the procedures, and the types
of all objects referenced) between these packages and procedure BD3 each time
BD3 references one of these packages.
Line 445 introduces the procedure (is the beginning of procedure BD3's
body), and the rest of the lines in Figure 21 are comments in the prologue.
- 20 -
BD3 - A Demonstration of Tasking in Ada
======================================================================
476 -- Line input from the console
477 INPUT : CONSOLE.OUTSTRING;
478
479 -- Number of continuous status reports displayed by the 'c'
480 -- command before control is returned to the console
481 NUMBER_OF_CONTINUOUS_STATUS_REPORTS : constant := 10;
482
Figure 22: Procedure BD3, Part 2 of 4 Figure 22
======================================================================
Figure 22 shows a local variable and a local constant in procedure BD3.
The variable INPUT is used to receive the line entered by the user when he is
prompted for input. The READ procedure in package CONSOLE is used to input
this line. The definition of the constant number of continuous status reports
is self-explanatory.
======================================================================
483 --
484 -- procedure BD3
485
486 begin -- mainline
487
488 -- This is the beginning of the main loop. In this loop,
489 -- a list of commands is printed on the console, the user
490 -- at the console (as CUSTOMER 0) enters one of these commands
491 -- followed by striking the RETURN key, and the command is
492 -- processed.
493 loop
494
495 -- Command listing and prompt
496 CONSOLE.WRITE("Enter");
497 CONSOLE.WRITE(CONSOLE.NEW_LINE);
498 CONSOLE.WRITE(" b for bank status");
499 CONSOLE.WRITE(CONSOLE.NEW_LINE);
500 CONSOLE.WRITE(" c for continuous bank status");
501 CONSOLE.WRITE(CONSOLE.NEW_LINE);
502 CONSOLE.WRITE(" s for start next customer");
503 CONSOLE.WRITE(CONSOLE.NEW_LINE);
504 CONSOLE.WRITE(" x for exit: ");
505 CONSOLE.READ(INPUT);
506
Figure 23: Procedure BD3, Part 3 of 4 Figure 23
======================================================================
Figure 23 shows the beginning of the executable code in procedure BD3.
This code starts after the "begin" statement on line 486, and the entirety of
this code is contained within the loop which starts on line 493.
- 21 -
BD3 - A Demonstration of Tasking in Ada
The first thing done in this loop is the presentation of the prompt to
the user (lines 496-504) and the input of the command from the user (line
505).
======================================================================
507 -- Interpretation and execution of input command
508 case INPUT(1) is
509 when 'b' | 'c' => -- Short or continuous bank status
510 -- report
511 BANK.PRINT_REPORT;
512 if INPUT(1) = 'c' then
513 for I in 1 .. NUMBER_OF_CONTINUOUS_STATUS_REPORTS loop
514 delay 5.0;
515 BANK.PRINT_REPORT;
516 CONSOLE.WRITE(CONSOLE.NEW_LINE);
517 end loop;
518 end if;
519
520 when 's' => -- Start up a new CUSTOMER
521 CUSTOMER_WORLD.ADD;
522
523 when 'x' => -- Exit program
524 CUSTOMER_WORLD.TERMINATE_ALL; -- Kill CUSTOMER tasks
525 BANK.STOP_WORK; -- Kill TELLER tasks
526 exit; -- Exit loop
527
528 when ' ' => -- Non-error on a null input line
529 null;
530
531 when others => -- Other commands are invalid
532 CONSOLE.WRITE("Invalid Command: ");
533 CONSOLE.WRITE(CONSOLE.TRIM(INPUT));
534 CONSOLE.WRITE(CONSOLE.NEW_LINE);
535
536 end case;
537
538 end loop;
539
540 end BD3;
Figure 24: Procedure BD3, Part 4 of 4 Figure 24
======================================================================
Figure 24 shows the rest of procedure BD3. The first letter of the
command just input (line 505 of Figure 23) is the target for the case
expression in line 508. If this letter is a lower-case 'b' (bank status) or
'c' (continuous bank status), the code in lines 509-519 will be executed. If
this letter is a lower-case 's' (start next customer), the code in lines
520-522 will be executed. If this letter is a lower-case 'x' (exit), the code
in lines 523-527 will be executed. If this letter is a space, nothing happens
(lines 528-530). If this letter is anything else, an error message is printed
- 22 -
BD3 - A Demonstration of Tasking in Ada
(lines 531-535). The loop itself ends on lines 538, and the procedure BD3
ends on line 540.
4 File Distribution 4 File Distribution
Figure 25 shows the files provided in the distribution of Bank Demo 3.
This document is in one-column format in the file PRINT.ME.
======================================================================
READ.ME An introduction to the distribution
PRINT.ME This document, ready to be printed as ASCII
text on 8 1/2" x 11" paper in elite type
BD3.SPR Source (in Borland's SPRINT) to the file PRINT.ME
CONSOLE.ADA Compilable Ada source code to package CONSOLE
RANDOM.ADA Compilable Ada source code to package RANDOM
BD3.ADA Compilable Ada source code to packages BANK
and CUSTOMER_WORLD and procedure BD3
Note: the compilation order is CONSOLE.ADA,
RANDOM.ADA, and BD3.ADA
CONSOLE.LST Listing of CONSOLE.ADA with each line numbered
RANDOM.LST Listing of RANDOM.ADA with each line numbered
BD3.LST Listing of BD3.ADA with each line numbered
BD3.EXE Executable binary of the BD3 system (run by
giving the command "BD3" at the MSDOS prompt)
Figure 25: Files Distributed as Part of Bank Demo 3 Figure 25
======================================================================
- 23 -
ContentsContents
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . 1
2 Execution of the Program . . . . . . . . . . . . . . . . . 3
3 Discussion of the Design . . . . . . . . . . . . . . . . . 9
4 File Distribution . . . . . . . . . . . . . . . . . . . 23
i
ii
FiguresFigures
Figure 1: The bank tellers can process four kinds of
transactions. . . . . . . . . . . . . . . . . . . . . 1
Figure 2: This code segment shows that the TELLER(n) tasks are
accessed like procedures. . . . . . . . . . . . . . . 2
Figure 3: When BD3 starts, there are no customers. . . . . . . . 3
Figure 4: The 's' command starts a new customer task. . . . . . 4
Figure 5: Another status display shows just a little activity by
the customer. . . . . . . . . . . . . . . . . . . . . 4
Figure 6: Five more tasks are started up. . . . . . . . . . . . 5
Figure 7: A continous bank status display shows a lot of activity
over a short time. . . . . . . . . . . . . . . . . . . 6
Figure 8: Two more customer tasks are started. . . . . . . . . . 7
Figure 9: Two more status reports are shown, each after some
delay. . . . . . . . . . . . . . . . . . . . . . . . . 8
Figure 10: Specification of Package CONSOLE, Part 1 of 4 . . . .10
Figure 11: Specification of Package CONSOLE, Part 2 of 4 . . . .11
Figure 12: Specification of Package CONSOLE, Part 3 of 4 . . . .12
Figure 13: Specification of Package CONSOLE, Part 4 of 4 . . . .13
Figure 14: Calling the Random Number Generator . . . . . . . . .13
Figure 15: Specification of Package RANDOM . . . . . . . . . . .14
Figure 16: Specification of Package BANK, Part 1 of 4 . . . . .15
Figure 17: Specification of Package BANK, Part 2 of 4 . . . . .15
Figure 18: Specification of Package BANK, Part 3 of 4 . . . . .16
Figure 19: Specification of Package BANK, Part 4 of 4 . . . . .17
Figure 20: Specification of Package CUSTOMER_WORLD . . . . . . .18
Figure 21: Procedure BD3, Part 1 of 4 . . . . . . . . . . . . .20
Figure 22: Procedure BD3, Part 2 of 4 . . . . . . . . . . . . .21
Figure 23: Procedure BD3, Part 3 of 4 . . . . . . . . . . . . .21
Figure 24: Procedure BD3, Part 4 of 4 . . . . . . . . . . . . .22
Figure 25: Files Distributed as Part of Bank Demo 3 . . . . . .23
iii